/**
 * Copyright © 2021-2025 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.resource.controller;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.jeeplus.aop.logging.annotation.ApiLog;
import com.jeeplus.core.excel.EasyExcelUtils;
import com.jeeplus.core.excel.ExcelOptions;
import com.jeeplus.core.excel.annotation.ExportMode;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.resource.domain.Venu;
import com.jeeplus.resource.domain.VenueStatus;
import com.jeeplus.resource.service.VenuService;
import com.jeeplus.resource.service.VenueStatusService;
import com.jeeplus.resource.service.dto.VenueRankDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.resource.domain.VenuApply;
import com.jeeplus.resource.service.dto.VenuApplyDTO;
import com.jeeplus.resource.service.mapstruct.VenuApplyWrapper;
import com.jeeplus.resource.service.VenuApplyService;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 场地状态Controller
 * @author 淋漓
 * @version 2024-08-19
 */

@Api(tags ="场地状态")
@RestController
@RequestMapping(value = "/resource/venuApply")
public class VenuApplyController {

	@Autowired
	private VenuApplyService venuApplyService;

	@Autowired
	private VenuApplyWrapper venuApplyWrapper;

	@Autowired
	private VenuService venuService;

	@Autowired
	private VenueStatusService venueStatusService;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 场地记录列表数据
	 */
	@ApiLog("查询场地记录列表数据")
	@ApiOperation(value = "查询场地记录列表数据")
	@PreAuthorize("hasAuthority('resource:venuApply:list')")
	@GetMapping("list")
	public ResponseEntity<IPage<VenuApplyDTO>> list(VenuApplyDTO venuApplyDTO, Page<VenuApply> page) throws Exception {
		QueryWrapper queryWrapper = QueryWrapperGenerator.buildQueryCondition (venuApplyDTO, VenuApplyDTO.class);
		if(venuApplyDTO.getStatus() != null && !venuApplyDTO.getStatus().isEmpty()){
			queryWrapper.eq("status", venuApplyDTO.getStatus());
		}
		if (venuApplyDTO.getTime() != null) {
			queryWrapper.eq("time", venuApplyDTO.getTime());
		}
		if (venuApplyDTO.getMyCreateTime() != null && !venuApplyDTO.getMyCreateTime().isEmpty()) {
			queryWrapper.like("date", venuApplyDTO.getMyCreateTime());
		}
		if(venuApplyDTO.getVenueName()!=null && !venuApplyDTO.getVenueName().isEmpty()){
			Venu venu = venuService.getOne(new QueryWrapper<Venu>()
					.eq("venue_name", venuApplyDTO.getVenueName()));
			if(venu!=null){
				queryWrapper.eq("venue_id", venu.getId());
			}
			else {
				return ResponseEntity.ok (new Page<>());
			}
		}
		if(!"1".equals(venuApplyDTO.getUserId())) {
			queryWrapper.eq("user_id", venuApplyDTO.getUserId());
		}
		IPage<VenuApplyDTO> result = venuApplyWrapper.toDTO ( venuApplyService.page (page, queryWrapper) );
		List<VenuApplyDTO> records = result.getRecords();
		setLevel(records);
		setVenueTime(records);
		setVenueName(records);
		return ResponseEntity.ok (result);
	}


	/**
	 * 根据Id获取场地记录数据
	 */
	@ApiLog("根据Id获取场地记录数据")
	@ApiOperation(value = "根据Id获取场地记录数据")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:view','resource:venuApply:add','resource:venuApply:edit')")
	@GetMapping("queryById")
	public ResponseEntity<VenuApplyDTO> queryById(String id) {
		return ResponseEntity.ok ( venuApplyWrapper.toDTO ( venuApplyService.getById ( id ) ) );
	}

	/**
	 * 查询最近预约成功、失败和正在使用的地点
	 */
	@ApiLog("查询最近预约成功、失败和正在使用的地点")
	@ApiOperation(value = "查询最近预约成功、失败和正在使用的地点")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:view','resource:venuApply:add','resource:venuApply:edit')")
	@GetMapping("queryRecent")
	public ResponseEntity<List<VenuApplyDTO>> recent(String userId) {
		List<VenuApply> list = new ArrayList<>();
		list.add(venuApplyService.getOne(new QueryWrapper<VenuApply>()
				.eq("user_id", userId)
				.eq("status", "已预约")
				.orderByDesc("date")
				.last("limit 1")));
		list.add(venuApplyService.getOne(new QueryWrapper<VenuApply>()
				.eq("user_id", userId)
				.eq("status", "已结束")
				.orderByDesc("date")
				.last("limit 1")));
		list.add(venuApplyService.getOne(new QueryWrapper<VenuApply>()
				.eq("user_id", userId)
				.eq("status", "使用中")
				.orderByDesc("date")
				.last("limit 1")));
		List<VenuApplyDTO> records=new ArrayList<>();
		for (VenuApply venuApply :list) {
			if(venuApply==null){
				records.add(null);
			}
			else {
				records.add(BeanUtil.copyProperties(venuApply,VenuApplyDTO.class));
			}
		}
		setVenueName(records);
		setVenueTime(records);
		return ResponseEntity.ok ( records );
	}

	/**
	 * 根据Id获取场地记录数据
	 */
	@ApiLog("根据Id获取场地记录数据")
	@ApiOperation(value = "根据Id获取场地记录数据")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:view','resource:venuApply:add','resource:venuApply:edit')")
	@GetMapping("queryRank")
	public ResponseEntity<List<VenueRankDTO>> queryRank(String userId) {
		if(userId!=null && !userId.isEmpty()){
			return ResponseEntity.ok ( venuApplyService.queryRank(userId) );
		}
		return ResponseEntity.ok ( new ArrayList<> () );
	}

	/**
	 * 根据Id获取场地每周预约数
	 */
	@ApiLog("根据Id获取场地每周预约数")
	@ApiOperation(value = "根据Id获取场地每周预约数")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:view','resource:venuApply:add','resource:venuApply:edit')")
	@GetMapping("queryVenueWeek")
	public ResponseEntity<List<String>> queryVenueWeek(String userId) {
		List<String> list=new ArrayList<>();
		if(userId!=null && !userId.isEmpty()){
			String venueWeek1 = (String) redisTemplate.opsForValue().get("venueWeek1");
			if(venueWeek1==null){
				list.add("0");
			}
			else {
				list.add(venueWeek1);
			}
			String venueWeek2 = (String) redisTemplate.opsForValue().get("venueWeek2");
			if(venueWeek2==null){
				list.add("0");
			}
			else {
				list.add(venueWeek2);
			}
			String venueWeek3 = (String) redisTemplate.opsForValue().get("venueWeek3");
			if(venueWeek3==null){
				list.add("0");
			}
			else {
				list.add(venueWeek3);
			}
			String venueWeek4 = (String) redisTemplate.opsForValue().get("venueWeek4");
			if(venueWeek4==null){
				list.add("0");
			}
			else {
				list.add(venueWeek4);
			}
			return ResponseEntity.ok ( list );
		}
		for (int i = 0; i < 4; i++) {
			list.add("0");
		}
		return ResponseEntity.ok ( list );
	}

	/**
	 * 保存场地记录
	 */
	@ApiLog("保存场地记录")
	@ApiOperation(value = "保存场地记录")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:add','resource:venuApply:edit')")
	@PostMapping("save")
	@Transactional
	public  ResponseEntity <String> save(@Valid @RequestBody VenuApplyDTO venuApplyDTO) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
        try {
			date= sdf.parse(venuApplyDTO.getMyCreateTime());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        venuApplyDTO.setDate(date);
		venuApplyDTO.setStatus("已预约");
		//新增或编辑表单保存
		venuApplyService.saveOrUpdate (venuApplyWrapper.toEntity (venuApplyDTO));
		setStatus(venuApplyDTO,"已占用");//在venue_status表修改该时间段数据
        return ResponseEntity.ok ( "预约成功" );
	}

	/**
	 * 保存场地记录
	 */
	@ApiLog("保存场地记录")
	@ApiOperation(value = "保存场地记录")
	@PreAuthorize("hasAnyAuthority('resource:venuApply:add','resource:venuApply:edit')")
	@PostMapping("update")
	@Transactional
	public  ResponseEntity <String> update(@Valid @RequestBody VenuApplyDTO venuApplyDTO) {
		venuApplyService.update(new LambdaUpdateWrapper<VenuApply>()
				.eq(VenuApply::getId,venuApplyDTO.getId())
				.set(VenuApply::getStatus,"已取消"));
		setStatus(venuApplyDTO,"空闲");//在venue_status表修改该时间段数据
        return ResponseEntity.ok ( "取消成功" );
	}


	/**
	 * 删除场地记录
	 */
	@ApiLog("删除场地记录")
	@ApiOperation(value = "删除场地记录")
	@PreAuthorize("hasAuthority('resource:venuApply:del')")
	@DeleteMapping("delete")
	public ResponseEntity <String> delete(String ids) {
		String idArray[] = ids.split(",");
        venuApplyService.removeByIds ( Lists.newArrayList ( idArray ) );
		return ResponseEntity.ok( "删除场地记录成功" );
	}

    /**
     * 导出场地记录数据
     *
     * @param venuApplyDTO
     * @param page
     * @param response
     * @throws Exception
     */
    @ApiLog("导出场地记录数据")
    @PreAuthorize("hasAnyAuthority('resource:venuApply:export')")
    @GetMapping("export")
    public void exportFile(VenuApplyDTO venuApplyDTO, Page <VenuApply> page, ExcelOptions options, HttpServletResponse response) throws Exception {
        String fileName = options.getFilename ( );
		QueryWrapper queryWrapper = QueryWrapperGenerator.buildQueryCondition (venuApplyDTO, VenuApplyDTO.class);
        if ( ExportMode.current.equals ( options.getMode ( ) ) ) { // 导出当前页数据

        } else if ( ExportMode.selected.equals ( options.getMode ( ) ) ) { // 导出选中数据
            queryWrapper.in ( "id", options.getSelectIds () );
        } else { // 导出全部数据
            page.setSize ( -1 );
            page.setCurrent ( 0 );
        }
        List < VenuApply> result = venuApplyService.page ( page, queryWrapper ).getRecords ( );
        EasyExcelUtils.newInstance ( venuApplyService, venuApplyWrapper ).exportExcel ( result,  options.getSheetName ( ), VenuApplyDTO.class, fileName,options.getExportFields (), response );
    }

    /**
     * 导入场地记录数据
     *
     * @return
     */
    @PreAuthorize("hasAnyAuthority('resource:venuApply:import')")
    @PostMapping("import")
    public ResponseEntity importFile(MultipartFile file) throws IOException {
        String result = EasyExcelUtils.newInstance ( venuApplyService, venuApplyWrapper ).importExcel ( file, VenuApplyDTO.class );
        return ResponseEntity.ok ( result );
    }

    /**
     * 下载导入场地记录数据模板
     *
     * @param response
     * @return
     */
    @PreAuthorize ("hasAnyAuthority('resource:venuApply:import')")
    @GetMapping("import/template")
    public void importFileTemplate(HttpServletResponse response) throws IOException {
        String fileName = "场地记录数据导入模板.xlsx";
        List<VenuApplyDTO> list = Lists.newArrayList();
        EasyExcelUtils.newInstance ( venuApplyService, venuApplyWrapper ).exportExcel ( list,  "场地记录数据", VenuApplyDTO.class, fileName, null, response );
    }

	/**
	 * 将时间标志转为具体时间段
	 * @param records
	 */
	public void setVenueTime(List<VenuApplyDTO> records){
		for (VenuApplyDTO record : records) {
			if(record!=null) {
				switch (record.getTime()) {
					case 0:
						record.setVenueTime("8：30-10：05");
						break;
					case 1:
						record.setVenueTime("10：25-12：00");
						break;
					case 2:
						record.setVenueTime("14：30-16：05");
						break;
					case 3:
						record.setVenueTime("16：15-17：50");
						break;
					case 4:
						record.setVenueTime("18：30-20：05");
						break;
					default:
						record.setVenueTime("20：15-21：50");
				}
			}
		}
	}

	/**
	 * 设置状态颜色
	 * @param records
	 */
	public void setLevel(List<VenuApplyDTO> records){
		for (VenuApplyDTO record : records) {
			if(record!=null) {
				if ("已预约".equals(record.getStatus())) {
					record.setLevel("primary");
				} else if ("已同意".equals(record.getStatus())) {
					record.setLevel("success");
				} else if ("已拒绝".equals(record.getStatus())) {
					record.setLevel("danger");
				} else if ("使用中".equals(record.getStatus())) {
					record.setLevel("success");
				} else {
					record.setLevel("info");
				}
			}
		}
	}

	/**
	 * 设置场地名称
	 * @param records
	 */
	public void setVenueName(List<VenuApplyDTO> records){
		for (VenuApplyDTO record : records) {
			if(record!=null) {
				record.setVenueName(venuService.getById(record.getVenueId()).getVenueName());
			}
		}
	}


	public void setStatus(VenuApplyDTO venuApplyDTO ,String status){
		String str="";
		switch (venuApplyDTO.getTime()){
			case 0:
				str="am1";
				break;
			case 1:
				str="am2";
				break;
			case 2:
				str="pm1";
				break;
			case 3:
				str="pm2";
				break;
			case 4:
				str="night1";
				break;
			case 5:
				str="night2";
				break;
		}
		if(!str.isEmpty()) {
			if(venuApplyDTO.getMyCreateTime()==null && venuApplyDTO.getDate()!=null){
				SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
				venuApplyDTO.setMyCreateTime(sdf.format(venuApplyDTO.getDate()));
			}
			venueStatusService.update(new UpdateWrapper<VenueStatus>()
					.eq("venue_id", venuApplyDTO.getVenueId())
					.like("date", venuApplyDTO.getMyCreateTime())
					.set(str, status));
		}
	}
}
